tailwindでCSS Module内でMulti SelectorなUtility Classを@applyすると壊れる
/icons/github.iconのIssue: https://github.com/tailwindlabs/tailwindcss/issues/3258
再現: https://github.com/tosuke-lab/miniature-octo-umbrella
tailwindを導入している状態で
code:css
.hoge {
@apply group-hover:text-white;
}
とかすると
code:css
.group:hover .hoge {
color: ...
}
みたいに展開された結果.groupもCSS Modulesによる修飾がかかって期待通りの動きをしなくなる
本当は
code:css
:global(.group:hover) .hoge { ... }
みたいになっていてほしい
しかしこれはCSS Modulesに対応している環境でないと動かないので、デフォルトをこれにするわけにはいかない
何らかのモードが必要になりそう?
@applyは任意のクラスをinjectすることができるが、グローバルに定義されている任意のMulti Selectorなクラスに対応するべきか?
結論
@applyをやめろ
回避
code:css
:global {
:local(.hoge) {
@apply group-hover:text-white;
}
}
と書く
展開されて
code:compiled.css
:global {
.group:hover :local(.hoge) {
@apply text-white;
}
}
になるため
わかるかよ
あらゆるCSSを:globalで囲み、セレクタに:localを付けるやつを作ればいいっぽいな!
どうやってCSS Modulesかどうか検証するんだ?
↓のアプローチは全て失敗です。悲しいね
実装
何らかの手段でCSS Modulesであるかの情報を得る
最悪configを拡張することになるだろうが、可能なら知らないうちにうまくやってくれてほしいという気持ちはある
自動はとりあえず考えない
supportsCSSModules: trueとかを書かせる
CSSとしてValidでないものを吐くので、デフォルトではoff
グローバルなセレクタを:global(...)で保護する
group-hover:やdark:のようなプレフィックスだけ守れればいい場合、https://github.com/tailwindlabs/tailwindcss/blob/master/src/util/prefixSelector.js に手を入れることで可能
少々アドホック
任意のシチュエーションに対応しようとする場合、@applyを展開している箇所に手を入れればいい
https://github.com/tailwindlabs/tailwindcss/blob/e7a36d22acaa47d8fb0162c2d80455a1e103f3ef/src/lib/substituteClassApplyAtRules.js#L229 このへんだろうけどちょっと抽象度が高くてキツい
どう展開されるかがそのファイルがCSS Modulesであるかに依存するので、これは険しい